﻿/**
Library: transition managing library (TraM)
Author: Valentyn Derkach 2007.07.04
———————————————————————————————————————————————————————————————————————————————————————————————————————————————————
*/

package com.bizmlib.tram
{
	import flash.display.DisplayObject;
	import flash.events.Event;
	import flash.geom.ColorTransform;
	import flash.text.TextField;
	
	
	public class Tint extends TraM
	{
		public namespace rgbtint;
	
		private var currentColorTransform:ColorTransform;
		private var finalColorTransform:ColorTransform;
		
		private static var INSPECTABLE_PROPERTIES:Array = ["alphaMultiplier", "alphaOffset", "blueMultiplier", "blueOffset", "greenMultiplier", "greenOffset", "redMultiplier", "redOffset"];
		private static var MULTIPLIERS:Object = {
			alphaMultiplier: 100,
			redMultiplier: 100,
			blueMultiplier: 100,
			greenMultiplier: 100,
			alphaOffset: 1,
			redOffset: 1,
			blueOffset: 1,
			greenOffset: 1
		};
		
	
		/**
		 * A normal Transitioning constructor. Note that propertiesObject can be either a color transform object
		 * (the one whose properties contain the current offset and percentage values for the specified color) or 
		 * a Number, which is a final color for the subject.
		 * @param	subjectObject		an object
		 * @param	propertiesObject	color data
		 * @param	tweenProcessor		tween processor
		 */
		public function Tint(subjectObject:DisplayObject = undefined, propertiesObject:Object = undefined, engine:IEngine = undefined)
		{
			super(subjectObject, propertiesObject, engine);
			setName("tint");
		}
		
		
		rgbtint function get subject():DisplayObject
		{
			return super.subject as DisplayObject;
		}
		
		
		
		override protected function doRender(event:Event):void
		{
			if(renderManager.checkProperty("colorTransform", true))
			{
				updateSubjectColorTransform();
			}
		}
		
		
		/**
		 * This transition requires a parsing of the properties object.
		 */
		override protected function onStart():void
		{
			if(!(subject is DisplayObject))
			{
				throw new Error(this + " can't start - subject is not a DisplayObject (or it's subclass) instance");
			}
			
			//trace("properties=" + properties);
			if(rgbtint::subject is TextField)
			{
				currentColorTransform = new ColorTransform();
				currentColorTransform.color = (rgbtint::subject as TextField).textColor;
			}
			else
			{
				currentColorTransform = rgbtint::subject.transform.colorTransform;
			}
			//trace("currentColorTransform=" + currentColorTransform);
			
			finalColorTransform = adaptProperties(properties);
			/**
			if(properties is ColorTransform)
			{
				finalColorTransform = properties as ColorTransform;
			}
			else
			{
				var colorValue:Number = 0;
				if(properties is Number)
				{
					colorValue = properties as Number;
				}
				finalColorTransform = new ColorTransform(0, 0, 0, 1, (colorValue&0xff0000)>>16, (colorValue&0x00ff00)>>8, colorValue&0x0000ff);
				//trace("finalColorTransform=" + finalColorTransform);
			}
			/**/
		}
		
		
		override protected function compareProperties(comparingProperties:Object):Boolean
		{
			var colorTransform:ColorTransform = adaptProperties(comparingProperties);
			return	(colorTransform.alphaMultiplier==finalColorTransform.alphaMultiplier) &&
					(colorTransform.alphaOffset==finalColorTransform.alphaOffset) &&
					(colorTransform.blueMultiplier==finalColorTransform.blueMultiplier) &&
					(colorTransform.blueOffset==finalColorTransform.blueOffset) &&
					(colorTransform.greenMultiplier==finalColorTransform.greenMultiplier) &&
					(colorTransform.greenOffset==finalColorTransform.greenOffset) &&
					(colorTransform.redMultiplier==finalColorTransform.redMultiplier) &&
					(colorTransform.redOffset==finalColorTransform.redOffset);
			//return super.compareProperties(adaptProperties(comparingProperties));
		}
		protected function adaptProperties(properties:Object):ColorTransform
		{
			if(properties is ColorTransform)
			{
				return properties as ColorTransform;
			}
			else
			{
				var colorValue:Number = 0;
				if(properties is Number)
				{
					colorValue = properties as Number;
				}
				return new ColorTransform(0, 0, 0, 1, (colorValue&0xff0000)>>16, (colorValue&0x00ff00)>>8, colorValue&0x0000ff);
				//trace("finalColorTransform=" + finalColorTransform);
			}
		}
		
		
		/**
		 * Perfoms a tint of MovieClip. It's an advanced tint so you can use any properties of
		 * color transformation object.
		 */
		override protected function transitionIteration():void
		{
			//trace(this + ".transitionIteration(" + arguments + ")");
			//trace(finalColorTransform);
			//trace(currentColorTransform);
			//trace("\n");
			
			for each(var propertyName:String in INSPECTABLE_PROPERTIES)
			{
				var multiplier:Number = MULTIPLIERS[propertyName] as Number;
				/**
				currentColorTransform[propertyName] = Math.round(engine.performCalculation(
					String(propertyName),
					currentColorTransform[propertyName]*multiplier,
					finalColorTransform[propertyName]*multiplier
				));
				currentColorTransform[propertyName] /= multiplier;
				/**/
				var newValue:Number = engine.performCalculation(
					String(propertyName),
					currentColorTransform[propertyName]*multiplier,
					finalColorTransform[propertyName]*multiplier
				);
				//newValue = Math.round(newValue);
				currentColorTransform[propertyName] = newValue / multiplier;
			}
			//properties.C.setTransform(properties.curCTrans);
			if(updateOnEnterFrame)
			{
				renderManager.start("colorTransform");
			}
			else
			{
				updateSubjectColorTransform();
			}
		}
		protected function updateSubjectColorTransform():void
		{
			//trace(this + ".updateSubjectColorTransform(" + arguments + ")");
			
			if(rgbtint::subject is TextField)
			{
				(rgbtint::subject as TextField).textColor = currentColorTransform.color;
			}
			else
			{
				rgbtint::subject.transform.colorTransform = currentColorTransform;
			}
		}
		
		
		override public function toString():String
		{
			return "[Tint	subject:" + subject + "]";
		}
	}
}